/**
 * 
 */
package unifor.filetransfer.transmissor;

import java.io.BufferedInputStream;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.net.Socket;

import unifor.filetransfer.Principal;
import unifor.filetransfer.receptor.ReceptorTransmissorThread;
import unifor.filetransfer.util.ConfiguracaoTO;
import unifor.filetransfer.util.TransmissaoUtil;

/**
 * @author Landim - Arthur Landim
 *
 */
public class Transmissor extends Thread {
	ConfiguracaoTO to;
	
    public void enviarArquivo(ConfiguracaoTO to) {
    	this.to = to;
    	
        conectar(to.getIpDestino(), to.getPorta());
        
        try {
			new ReceptorTransmissorThread(new BufferedInputStream(Principal.clienteSocket.getInputStream())).start();
		} catch (IOException e1) {
			// TODO Auto-generated catch block
			Principal.logTrans(e1.getMessage());
		}
    	start();
    }
    
    @Override
    public void run() {
    	// TODO Auto-generated method stub
    	super.run();
        
        
        byte[] cabecalho = TransmissaoUtil.gerarCabecalhoPduEnvio(to);
        byte[] segmento = new byte[to.getTamanhoSegmento()];
        Principal.logTrans("Iniciando transmissao na porta " + to.getPorta());
        
        int tamanhoArquivo = to.getTamanhoArquivo();
        Principal.setBarraMax(tamanhoArquivo);
        Principal.zeraBarraMax();
        //enviando o primeiro pacote
        int restante = to.getTamanhoSegmento() - cabecalho.length;
        int index = 1;
        
        InputStream inArquivo = null;
		try {
			inArquivo = new BufferedInputStream(new FileInputStream(to.getNomeArquivo()));
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
        
        
        if (restante > 0) {
            if (restante > tamanhoArquivo) {
                restante = tamanhoArquivo;
                segmento = new byte[restante + cabecalho.length];
            }
            
            
            byte[] arquivo = TransmissaoUtil.lerBytesDoArquivo(inArquivo, restante);
            System.arraycopy(cabecalho, 0, segmento, 0, cabecalho.length);
            System.arraycopy(arquivo, 0, segmento, cabecalho.length, arquivo.length);
            
            transmitirDados(segmento, index++);
        }
        
//        restante = segmento.length;
        
        while ( (restante - to.getTamanhoArquivo() < segmento.length)
                || restante < to.getTamanhoArquivo()) {
            byte[] arquivo = TransmissaoUtil.lerBytesDoArquivo(inArquivo, segmento.length);
            if (arquivo == null) {
            	Principal.logTrans("Terminou o arquivo" );
            	break;
            }
            segmento = new byte[arquivo.length];
            System.arraycopy(arquivo, 0, segmento, 0, arquivo.length);
            restante += segmento.length;
            transmitirDados(segmento, index++);
        }
        try {
        	inArquivo.close();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		System.out.println("fim de transmissao");
		

    }
    
    public static void transmitirDados(byte[] segmento, int pos) {
        //Enviar
        try {
            Principal.logTrans("=========================");
            Principal.logTrans("Enviando pacote " + pos);
            Principal.logTrans("quantidade de bytes : " + segmento.length);
            Principal.incrementaEnvio(segmento.length);
            Principal.clienteSocket.getOutputStream().write(segmento);
            Principal.clienteSocket.getOutputStream().flush();
            Principal.logTrans("Pacote enviado com sucesso");
//            sleep(200);
        } catch (Exception e) {
            Principal.logTrans("Erro ao enviar arquivo");
            Principal.logTrans(e.getMessage());
        }
    }

    public void conectar(String host, int porta) {
        try {
            Principal.clienteSocket = new Socket(host, porta);
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
            Principal.logTrans("Erro ao abrir conexao");
            Principal.logTrans(e.getMessage());
            
        }
        
    }



}
